package net.lucene.chapter9.search;

import net.lucene.chapter9.query.MyQueryParser;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 【第九章】高级搜索之自定义QueryParser
 *
 * @author Barudisshu
 */
public class AdvancedSearch {

    // 索引存储目录
    private static final String PATH_OF_INDEX = "chapter9-demo/src/main/resources/lucene/09_index";


    private Directory directory;
    private IndexReader reader;

    public AdvancedSearch() {

        // 文件大小
        int[] sizes = {90, 10, 20, 10, 60, 50};
        // 文件名
        String[] names = {"Michael.java", "Scofield.ini", "Tbag.txt", "Jack", "Jade", "Jadyer"};
        // 文件内容
        String[] contents = {"my java blog is http://blog.csdn.net/jadyer",
                "my Java Website is http://www.jadyer.cn",
                "my name is jadyer",
                "I am a Java Developer",
                "I am from Haerbin",
                "I like java of Lucene"};
        // 文件日期
        Date[] dates = new Date[sizes.length];
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        IndexWriter writer = null;
        Document doc;
        try {
            dates[0] = sdf.parse("20130407 15:25:30");
            dates[1] = sdf.parse("20130407 16:30:45");
            dates[2] = sdf.parse("20130213 11:15:25");
            dates[3] = sdf.parse("20130808 09:30:55");
            dates[4] = sdf.parse("20130526 13:54:22");
            dates[5] = sdf.parse("20130701 17:35:34");
            directory = FSDirectory.open(new File(PATH_OF_INDEX));
            writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_36, new StandardAnalyzer(Version.LUCENE_36)));
            writer.deleteAll();
            for (int i = 0; i < sizes.length; i++) {
                doc = new Document();
                doc.add(new NumericField("size", Field.Store.YES, true).setIntValue(sizes[i]));
                doc.add(new Field("name", names[i], Field.Store.YES, Field.Index.ANALYZED_NO_NORMS));
                doc.add(new Field("content", contents[i], Field.Store.NO, Field.Index.ANALYZED));
                doc.add(new NumericField("date", Field.Store.YES, true).setLongValue(dates[i].getTime()));
                writer.addDocument(doc);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != writer) {
                try {
                    writer.close();
                } catch (IOException ce) {
                    ce.printStackTrace();
                }
            }
        }
    }


    /**
     * 获取IndexReader实例
     */
    private IndexReader getIndexReader() {
        try {
            if (reader == null) {
                reader = IndexReader.open(directory);
            } else {
                //if the index was changed since the provided reader was opened, open and return a new reader; else,return null
                //如果当前reader在打开期间index发生改变,则打开并返回一个新的IndexReader,否则返回null
                IndexReader ir = IndexReader.openIfChanged(reader);
                if (ir != null) {
                    reader.close(); //关闭原reader
                    reader = ir;    //赋予新reader
                }
            }
            return reader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null; //发生异常则返回null
    }


    /**
     * 自定义QueryParser的搜索
     *
     * @param expr 搜索的表达式
     */
    public void searchByCustomQueryParser(String expr) {
        IndexSearcher searcher = new IndexSearcher(this.getIndexReader());
        QueryParser parser = new MyQueryParser(Version.LUCENE_36, "content", new StandardAnalyzer(Version.LUCENE_36));
        try {
            Query query = parser.parse(expr);
            TopDocs tds = searcher.search(query, 10);
            for (ScoreDoc sd : tds.scoreDocs) {

                Document doc = searcher.doc(sd.doc);
                System.out.print("文档编号=" + String.format("%02d",sd.doc) + "  文档权值=" + doc.getBoost() + "  文档评分=" + sd.score + "    ");
                System.out.println("size=" + doc.get("size") + "  date=" + new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(new Date(Long.parseLong(doc.get("date")))) + "  name=" + doc.get("name"));
            }
        } catch (ParseException e) {
            System.err.println(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                searcher.close(); //记得关闭IndexSearcher
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
